--[[ MyMinimapButton

    This is an embedded library intended to be used by other mods.
    It's not a standalone mod.

    See MyMinimapButton_API_readme.txt for more info.
]]

local version = 2.3

if not MyMinimapButton or MyMinimapButton.Version<version then

  MyMinimapButton = {

    Version = version,      -- for version checking

    -- Dynamically create a button
    --   modName = name of the button (mandatory)
    --   modSettings = table where SavedVariables are stored for the button (optional)
    --   initSettings = table of default settings (optional)
    Create = function(self,modName,modSettings,initSettings)
        if not modName or _G[modName.."MinimapButton"] then
            return
        end
        initSettings = initSettings or {}
        modSettings = modSettings or {}
        self.Buttons = self.Buttons or {}

        local frameName = modName.."MinimapButton"
        local frame = CreateFrame("Button",frameName,Minimap)
        frame:SetWidth(31)
        frame:SetHeight(31)
        frame:SetFrameStrata("LOW")
        frame:SetToplevel(1) -- enabled in 1.10.2
        frame:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
        frame:SetPoint("TOPLEFT",Minimap,"TOPLEFT")
        local icon = frame:CreateTexture(frameName.."Icon","BACKGROUND")
        icon:SetTexture(initSettings.icon or "Interface\\Icons\\INV_Misc_QuestionMark")
        icon:SetWidth(20)
        icon:SetHeight(20)
        icon:SetPoint("TOPLEFT",frame,"TOPLEFT",7,-5)
        local overlay = frame:CreateTexture(frameName.."Overlay","OVERLAY")
        overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
        overlay:SetWidth(53)
        overlay:SetHeight(53)
        overlay:SetPoint("TOPLEFT",frame,"TOPLEFT")

        frame:RegisterForClicks("LeftButtonUp","RightButtonUp")
        frame:SetScript("OnClick",self.OnClick)

        frame:SetScript("OnMouseDown",self.OnMouseDown)
        frame:SetScript("OnMouseUp",self.OnMouseUp)
        frame:SetScript("OnEnter",self.OnEnter)
        frame:SetScript("OnLeave",self.OnLeave)

        frame:RegisterForDrag("LeftButton")
        frame:SetScript("OnDragStart",self.OnDragStart)
        frame:SetScript("OnDragStop",self.OnDragStop)

        frame.tooltipTitle = modName
        frame.leftClick = initSettings.left
        frame.rightClick = initSettings.right
        frame.tooltipText = initSettings.tooltip

        local firstUse = 1
        for i,v in pairs(modSettings) do
            firstUse = nil -- modSettings has been populated before
        end
        if firstUse then
            -- define modSettings from initSettings
            modSettings.drag = initSettings.drag
            modSettings.enabled = initSettings.enabled
            modSettings.position = initSettings.position
            modSettings.radius = initSettings.radius
            modSettings.locked = initSettings.locked
        end
        -- define modSettings from defaults
        if not modSettings.drag then modSettings.drag = "CIRCLE" end
        if not modSettings.enabled then modSettings.enabled = 1 end
        if not modSettings.position then modSettings.position = self:GetDefaultPosition() end
        if not modSettings.radius then modSettings.radius = 80 end
        frame.modSettings = modSettings

        table.insert(self.Buttons,modName)
        self:SetEnable(modName,modSettings.enabled)
    end,

    -- Changes the icon of the button.
    --   value = texture path, ie: "Interface\\AddOn\\MyMod\\MyModIcon"
    SetIcon = function(self,modName,value)
        if value and _G[modName.."MinimapButton"] then
            _G[modName.."MinimapButtonIcon"]:SetTexture(value)
        end
    end,

    -- Sets the left-click function.
    --   value = function
    SetLeftClick = function(self,modName,value)
        if value and _G[modName.."MinimapButton"] then
            _G[modName.."MinimapButton"].leftClick = value
        end
    end,

    -- Sets the right-click function.
    --  value = function
    SetRightClick = function(self,modName,value)
        if value and _G[modName.."MinimapButton"] then
            _G[modName.."MinimapButton"].rightClick = value
        end
    end,

    -- Sets the drag route.
    --   value = "CIRCLE" or "SQUARE"
    SetDrag = function(self,modName,value)
        local button = _G[modName.."MinimapButton"]
        if button and (value=="CIRCLE" or value=="SQUARE") then
            button.modSettings.drag = value
            self:Move(modName)
        end
    end,

    -- Locks minimap button from moving
    --   value = 0/nil/false or 1/non-nil/true
    SetLock = function(self,modName,value)
        local button = _G[modName.."MinimapButton"]
        if value==0 then value = nil end
        if button then
            button.modSettings.locked = (value and 1) or nil
        end
    end,

    -- Enables or disables the minimap button
    --    value = 0/nil/false or 1/non-nil/true
    SetEnable = function(self,modName,value)
        local button = _G[modName.."MinimapButton"]
        if button then
            button.modSettings.enabled = value
            if (value and (value == 1 or value == true)) then
                button:Show()
                self:Move(modName,nil,1)
            else
                button:Hide()
            end
        end
    end,

    -- Returns a setting of this minimap button
    --   setting = "LOCKED", "ENABLED", "DRAG" or "POSITION"
    GetSetting = function(self,modName,setting)
        local button = _G[modName.."MinimapButton"]
        setting = string.lower(setting or "")
        if button and button.modSettings[setting] then
            return button.modSettings[setting]
        end
    end,

    -- Sets the tooltip text.
    --   value = string (can include \n)
    SetTooltip = function(self,modName,value)
        local button = _G[modName.."MinimapButton"]
        if button and value then
            button.tooltipText = value
        end
    end,

    -- Moves the button.
    --  newPosition = degree angle to display the button (optional)
    --  force = force move irregardless of locked status
    Move = function(self,modName,newPosition,force)
        local button = _G[modName.."MinimapButton"]
        if button and (not button.modSettings.locked or force) then
            button.modSettings.position = newPosition or button.modSettings.position
            local xpos,ypos
            local angle = button.modSettings.position
            if angle then
                if button.modSettings.drag=="SQUARE" then
                    xpos = 110 * cos(angle)
                    ypos = 110 * sin(angle)
                    xpos = math.max(-82,math.min(xpos,84))
                    ypos = math.max(-86,math.min(ypos,82))
                else
                    xpos = button.modSettings.radius * cos(angle)
                    ypos = button.modSettings.radius * sin(angle)
                end
                button:SetPoint("TOPLEFT","Minimap","TOPLEFT",54-xpos,ypos-54)
            end
        end
    end,

    -- Debug. Use no parameters to list all created buttons.
    Debug = function(self,modName)
        DEFAULT_CHAT_FRAME:AddMessage("MyMinimapButton version = "..self.Version)
        if modName then
            DEFAULT_CHAT_FRAME:AddMessage("Button: \""..modName.."\"")
            local button = _G[modName.."MinimapButton"]
            if button then
                DEFAULT_CHAT_FRAME:AddMessage("positon = "..tostring(button.modSettings.position))
                DEFAULT_CHAT_FRAME:AddMessage("enabled = "..tostring(button.modSettings.enabled))
                DEFAULT_CHAT_FRAME:AddMessage("drag = "..tostring(button.modSettings.drag))
                DEFAULT_CHAT_FRAME:AddMessage("locked = "..tostring(button.modSettings.locked))
            else
                DEFAULT_CHAT_FRAME:AddMessage("button not defined")
            end
        else
            DEFAULT_CHAT_FRAME:AddMessage("Buttons created:")
            for i=1,table.getn(self.Buttons) do
                DEFAULT_CHAT_FRAME:AddMessage("\""..self.Buttons[i].."\"")
            end
        end
    end,

    --[[ Internal functions: do not call anything below here ]]

    -- this gets a new default position by increments of 20 degrees
    GetDefaultPosition = function(self)
        local position,found = 0,1,0

        while found do
            found = nil
            for i=1,table.getn(self.Buttons) do
                if _G[self.Buttons[i].."MinimapButton"].modSettings.position==position then
                    position = position + 20
                    found = 1
                end
            end
            found = (position>340) and 1 or found -- leave if we've done full circle
        end
        return position
    end,

    OnMouseDown = function(self, button)
		local name = self:GetName();
        _G[name.."Icon"]:SetTexCoord(.1,.9,.1,.9)
    end,

    OnMouseUp = function(self, button)
		local name = self:GetName();
        _G[name.."Icon"]:SetTexCoord(0,1,0,1)
    end,

    OnEnter = function(self)
        GameTooltip_SetDefaultAnchor(GameTooltip,UIParent)
        GameTooltip:AddLine(self.tooltipTitle)
        GameTooltip:AddLine(self.tooltipText,.8,.8,.8,1)
        GameTooltip:Show()
    end,

    OnLeave = function(self)
        GameTooltip:Hide()
    end,

    OnDragStart = function(self)
        MyMinimapButton:OnMouseDown(self)
        self:LockHighlight()
        self:SetScript("OnUpdate",MyMinimapButton.OnUpdate)
    end,

    OnDragStop = function(self)
        self:SetScript("OnUpdate",nil)
        self:UnlockHighlight()
        MyMinimapButton:OnMouseUp(self)
    end,

OnUpdate = function(self)
        local xpos,ypos = GetCursorPosition()
        local xmin,ymin = Minimap:GetLeft(), Minimap:GetBottom()
        xpos = xmin-xpos/Minimap:GetEffectiveScale()+70
        ypos = ypos/Minimap:GetEffectiveScale()-ymin-70
        self.modSettings.position = math.deg(math.atan2(ypos,xpos))
        if (IsAltKeyDown()) then
            local radius = (xpos^2 + ypos^2)^0.5
            if (radius < 80) then
                radius = 80
            end
            if (radius > 140) then
                radius = 140
            end
            self.modSettings.radius = radius
        end
        local modName = string.gsub(self:GetName() or "","MinimapButton$","")
        MyMinimapButton:Move(modName)
    end,

	OnClick = function(self, arg1, down)
        if arg1=="LeftButton" and self.leftClick then
            self.leftClick()
        elseif arg1=="RightButton" and self.rightClick then
            self.rightClick()
        end
    end

  }

end
